Sanitise failsafe callback. The safe pf handler stuff was madness.
If it turns out to be needed, there must be a better way.
# Hypervisor uses this for application faults while it executes.
ENTRY(failsafe_callback)
- pushal
- call SYMBOL_NAME(install_safe_pf_handler)
- movl 32(%esp),%ebx
-1: movl %ebx,%ds
- movl 36(%esp),%ebx
-2: movl %ebx,%es
- movl 40(%esp),%ebx
-3: movl %ebx,%fs
- movl 44(%esp),%ebx
-4: movl %ebx,%gs
- call SYMBOL_NAME(install_normal_pf_handler)
- popal
- addl $16,%esp
+1: popl %ds
+2: popl %es
+3: popl %fs
+4: popl %gs
5: iret
.section .fixup,"ax"; \
-6: xorl %ebx,%ebx; \
+6: movl $0,(%esp); \
jmp 1b; \
-7: xorl %ebx,%ebx; \
+7: movl $0,(%esp); \
jmp 2b; \
-8: xorl %ebx,%ebx; \
+8: movl $0,(%esp); \
jmp 3b; \
-9: xorl %ebx,%ebx; \
+9: movl $0,(%esp); \
jmp 4b; \
10: pushl %ss; \
popl %ds; \
addl $12,%esp ; \
jmp ret_from_exception ;
PAGE_FAULT_STUB(page_fault, do_page_fault)
-PAGE_FAULT_STUB(safe_page_fault, do_safe_page_fault)
ENTRY(machine_check)
pushl $0
asmlinkage void stack_segment(void);
asmlinkage void general_protection(void);
asmlinkage void page_fault(void);
-asmlinkage void safe_page_fault(void);
asmlinkage void coprocessor_error(void);
asmlinkage void simd_coprocessor_error(void);
asmlinkage void alignment_check(void);
cpu_init();
}
-
-
-/*
- * install_safe_pf_handler / install_normal_pf_handler:
- *
- * These are used within the failsafe_callback handler in entry.S to avoid
- * taking a full page fault when reloading FS and GS. This is because FS and
- * GS could be invalid at pretty much any point while Xenolinux executes (we
- * don't set them to safe values on entry to the kernel). At *any* point Xen
- * may be entered due to a hardware interrupt --- on exit from Xen an invalid
- * FS/GS will cause our failsafe_callback to be executed. This could occur,
- * for example, while the mmu_update_queue is in an inconsistent state. This
- * is disastrous because the normal page-fault handler touches the update
- * queue!
- *
- * Fortunately, within the failsafe handler it is safe to force DS/ES/FS/GS
- * to zero if they cannot be reloaded -- at this point executing a normal
- * page fault would not change this effect. The safe page-fault handler
- * ensures this end result (blow away the selector value) without the dangers
- * of the normal page-fault handler.
- *
- * NB. Perhaps this can all go away after we have implemented writable
- * page tables. :-)
- */
-
-asmlinkage void do_safe_page_fault(struct pt_regs *regs,
- unsigned long error_code,
- unsigned long address)
-{
- unsigned long fixup;
-
- if ( (fixup = search_exception_table(regs->eip)) != 0 )
- {
- regs->eip = fixup;
- return;
- }
-
- die("Unhandleable 'safe' page fault!", regs, error_code);
-}
-
-unsigned long install_safe_pf_handler(void)
-{
- static trap_info_t safe_pf[] = {
- { 14, 0, __KERNEL_CS, (unsigned long)safe_page_fault },
- { 0, 0, 0, 0 }
- };
- unsigned long flags;
- local_irq_save(flags);
- HYPERVISOR_set_trap_table(safe_pf);
- return flags; /* This is returned in %%eax */
-}
-
-__attribute__((regparm(3))) /* This function take its arg in %%eax */
-void install_normal_pf_handler(unsigned long flags)
-{
- static trap_info_t normal_pf[] = {
- { 14, 0, __KERNEL_CS, (unsigned long)page_fault },
- { 0, 0, 0, 0 }
- };
- HYPERVISOR_set_trap_table(normal_pf);
- local_irq_restore(flags);
-}
# Hypervisor uses this for application faults while it executes.
ENTRY(failsafe_callback)
- pushal
- call install_safe_pf_handler
- movl 32(%esp),%ebx
-1: movl %ebx,%ds
- movl 36(%esp),%ebx
-2: movl %ebx,%es
- movl 40(%esp),%ebx
-3: movl %ebx,%fs
- movl 44(%esp),%ebx
-4: movl %ebx,%gs
- call install_normal_pf_handler
- popal
- addl $16,%esp
+1: popl %ds
+2: popl %es
+3: popl %fs
+4: popl %gs
5: iret
.section .fixup,"ax"; \
-6: xorl %ebx,%ebx; \
+6: movl $0,(%esp); \
jmp 1b; \
-7: xorl %ebx,%ebx; \
+7: movl $0,(%esp); \
jmp 2b; \
-8: xorl %ebx,%ebx; \
+8: movl $0,(%esp); \
jmp 3b; \
-9: xorl %ebx,%ebx; \
+9: movl $0,(%esp); \
jmp 4b; \
10: pushl %ss; \
popl %ds; \
addl $12,%esp ; \
jmp ret_from_exception ;
PAGE_FAULT_STUB(page_fault, do_page_fault)
-PAGE_FAULT_STUB(safe_page_fault, do_safe_page_fault)
#ifdef CONFIG_X86_MCE
ENTRY(machine_check)
asmlinkage void lcall7(void);
asmlinkage void lcall27(void);
-asmlinkage void safe_page_fault(void);
-
/* Do we ignore FPU interrupts ? */
char ignore_fpu_irq = 0;
*/
cpu_init();
}
-
-
-/*
- * install_safe_pf_handler / install_normal_pf_handler:
- *
- * These are used within the failsafe_callback handler in entry.S to avoid
- * taking a full page fault when reloading FS and GS. This is because FS and
- * GS could be invalid at pretty much any point while Xen Linux executes (we
- * don't set them to safe values on entry to the kernel). At *any* point Xen
- * may be entered due to a hardware interrupt --- on exit from Xen an invalid
- * FS/GS will cause our failsafe_callback to be executed. This could occur,
- * for example, while the mmmu_update_queue is in an inconsistent state. This
- * is disastrous because the normal page-fault handler touches the update
- * queue!
- *
- * Fortunately, within the failsafe handler it is safe to force DS/ES/FS/GS
- * to zero if they cannot be reloaded -- at this point executing a normal
- * page fault would not change this effect. The safe page-fault handler
- * ensures this end result (blow away the selector value) without the dangers
- * of the normal page-fault handler.
- *
- * NB. Perhaps this can all go away after we have implemented writable
- * page tables. :-)
- */
-
-asmlinkage void do_safe_page_fault(struct pt_regs *regs,
- unsigned long error_code,
- unsigned long address)
-{
- if (!fixup_exception(regs))
- die("Unhandleable 'safe' page fault!", regs, error_code);
-}
-
-unsigned long install_safe_pf_handler(void)
-{
- static trap_info_t safe_pf[] = {
- { 14, 0, __KERNEL_CS, (unsigned long)safe_page_fault },
- { 0, 0, 0, 0 }
- };
- unsigned long flags;
- local_irq_save(flags);
- HYPERVISOR_set_trap_table(safe_pf);
- return flags; /* This is returned in %%eax */
-}
-
-__attribute__((regparm(3))) /* This function take its arg in %%eax */
-void install_normal_pf_handler(unsigned long flags)
-{
- static trap_info_t normal_pf[] = {
- { 14, 0, __KERNEL_CS, (unsigned long)page_fault },
- { 0, 0, 0, 0 }
- };
- HYPERVISOR_set_trap_table(normal_pf);
- local_irq_restore(flags);
-}